home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / Music / EDIT / AmiSOX3.3 / dist / echo.c < prev    next >
C/C++ Source or Header  |  1995-08-23  |  5KB  |  220 lines

  1.  
  2. /*
  3.  * July 5, 1991
  4.  * Copyright 1991 Lance Norskog And Sundry Contributors
  5.  * This source code is freely redistributable and may be used for
  6.  * any purpose.  This copyright notice must be maintained. 
  7.  * Lance Norskog And Sundry Contributors are not responsible for 
  8.  * the consequences of using this software.
  9.  */
  10.  
  11. /*
  12. **     Echo effect. based on:
  13. **
  14. ** echoplex.c - echo generator
  15. **
  16. ** Copyright (C) 1989 by Jef Poskanzer.
  17. **
  18. ** Permission to use, copy, modify, and distribute this software and its
  19. ** documentation for any purpose and without fee is hereby granted, provided
  20. ** that the above copyright notice appear in all copies and that both that
  21. ** copyright notice and this permission notice appear in supporting
  22. ** documentation.  This software is provided "as is" without express or
  23. ** implied warranty.
  24. */
  25.  
  26. /*
  27.  * Sound Tools echo effect file.
  28.  */
  29.  
  30. #ifdef    AMIGA
  31. #include <stdlib.h> /* Harmless, and prototypes atof() etc. --dgc */
  32. #endif
  33. #include <math.h>
  34. #include "st.h"
  35.  
  36. #define FADE_THRESH 10
  37. #define MYBUFSIZ 256
  38. #define DELAYBUFSIZ ( 50L * MAXRATE )
  39. #define MAXDELAYS 30
  40.  
  41. struct echoplex {
  42.     int    counter;            
  43.     int    numdelays;
  44.     long    *delaybuf;
  45.     float    delay[MAXDELAYS], atten[MAXDELAYS];
  46.     long    samples[MAXDELAYS], maxsamples;
  47.     long    pl, ppl, pppl;
  48. };
  49.  
  50. /* Private data for SKEL file */
  51. typedef struct echostuff {
  52.     struct    echoplex *echoplex;
  53. } *echo_t;
  54.  
  55. #ifndef abs
  56. #define abs(a) ((a) >= 0 ? (a) : -(a))
  57. #endif
  58.  
  59. long clip24();
  60.  
  61. IMPORT writing;
  62.  
  63. /*
  64.  * Process options
  65.  */
  66. echo_getopts(effp, n, argv) 
  67. eff_t effp;
  68. int n;
  69. char **argv;
  70. {
  71.     echo_t echo = (echo_t) effp->priv;
  72.     struct echoplex *e;
  73.     int i;
  74.  
  75.     echo->echoplex = (struct echoplex *) malloc(sizeof(struct echoplex));
  76.     e = echo->echoplex;
  77.     e->numdelays = 0;
  78.     e->maxsamples = 0;
  79.  
  80.     if ((n == 0) || (n & 1))
  81.         fail("Usage: echo delay attenuation [ delay attenuation ... ]");
  82.  
  83.     i = 0;
  84.     while (i < n) {
  85.         /* Linux bug and it's cleaner. */
  86.         sscanf(argv[i++], "%f", &e->delay[e->numdelays]);
  87.         sscanf(argv[i++], "%f", &e->atten[e->numdelays]);
  88.  
  89.         e->numdelays++;
  90.     }
  91. }
  92.  
  93. /*
  94.  * Prepare for processing.
  95.  */
  96. echo_start(effp)
  97. eff_t effp;
  98. {
  99.     echo_t echo = (echo_t) effp->priv;
  100.     struct    echoplex *e = echo->echoplex;
  101.     int i;
  102.  
  103.     for(i = 0; i < e->numdelays; i++) {
  104.         e->samples[i] = e->delay[i] * effp->ininfo.rate;
  105.         if ( e->samples[i] < 1 )
  106.             fail(" delay must positive, aye!");
  107.         if ( e->samples[i] > DELAYBUFSIZ )
  108.             fail("Echo: delay must be less than %g seconds",
  109.                 DELAYBUFSIZ / (float) effp->ininfo.rate );
  110.         if ( e->atten[i] < 0.0 )
  111.             fail("attenuation must positive, aye!\n" );
  112.         if ( e->samples[i] > e->maxsamples )
  113.             e->maxsamples = e->samples[i];
  114.     }
  115.     if (! (e->delaybuf = (long *) malloc(sizeof (long) * e->maxsamples)))
  116.         fail("Echo: Cannot malloc %d bytes\n", 
  117.             sizeof(long) * e->maxsamples);
  118.     for ( i = 0; i < e->maxsamples; ++i )
  119.         e->delaybuf[i] = 0;
  120.     e->pppl = e->ppl = e->pl = 0x7fffff;        /* fade-outs */
  121.     e->counter = 0;
  122. }
  123.  
  124. /*
  125.  * Processed signed long samples from ibuf to obuf.
  126.  * Return number of samples processed.
  127.  */
  128.  
  129. echo_flow(effp, ibuf, obuf, isamp, osamp)
  130. eff_t effp;
  131. long *ibuf, *obuf;
  132. int *isamp, *osamp;
  133. {
  134.     echo_t echo = (echo_t) effp->priv;
  135.     struct    echoplex *e = echo->echoplex;
  136.     int len, done;
  137.     int i, j;
  138.     
  139.     long l;
  140.  
  141.     i = e->counter;
  142.     len = ((*isamp > *osamp) ? *osamp : *isamp);
  143.     for(done = 0; done < len; done++) {
  144.         /* Store delays as 24-bit signed longs */
  145.         l = *ibuf++ / 256;
  146.         for ( j = 0; j < e->numdelays; ++j )
  147.             l = l + 
  148. e->delaybuf[( i + e->maxsamples - e->samples[j]) % e->maxsamples] * e->atten[j];
  149.         l = clip24(l);
  150.         e->delaybuf[i] = l;
  151.         *obuf++ = l * 256;
  152.         i++;        /* XXX need a % maxsamples here ? */
  153.         i %= e->maxsamples;
  154.     }
  155.     e->counter = i;
  156.     /* processed all samples */
  157. }
  158.  
  159. /*
  160.  * Drain out echo lines. 
  161.  */
  162. echo_drain(effp, obuf, osamp)
  163. eff_t effp;
  164. long *obuf;
  165. long *osamp;
  166. {
  167.     echo_t echo = (echo_t) effp->priv;
  168.     struct    echoplex *e = echo->echoplex;
  169.     long l;
  170.     int i, j, done;
  171.  
  172.     i = e->counter;
  173.     done = 0;
  174.     /* drain out delay samples */
  175.     do {
  176.         l = 0;
  177.         for ( j = 0; j < e->numdelays; ++j )
  178.             l += 
  179. e->delaybuf[(i + e->maxsamples - e->samples[j]) % e->maxsamples] * e->atten[j];
  180.         l = clip24(l);
  181.         e->delaybuf[i] = l;
  182.         obuf[done++] = l * 256;
  183.         e->pppl = e->ppl;
  184.         e->ppl = e->pl;
  185.         e->pl = l;
  186.         i++;        /* need a % maxsamples here ? */
  187.         i %= e->maxsamples;
  188.     } while((done < *osamp) && 
  189.         ((abs(e->pl) + abs(e->ppl) + abs(e->pppl)) > FADE_THRESH));
  190.     e->counter = i;
  191.     *osamp = done;
  192.     /* drain will not be called again */
  193. }
  194.  
  195. /*
  196.  * Clean up echo effect.
  197.  */
  198. echo_stop(effp)
  199. eff_t effp;
  200. {
  201.     echo_t echo = (echo_t) effp->priv;
  202.  
  203.     free((char *) echo->echoplex);
  204.     echo->echoplex = (struct echoplex *) -1;   /* guaranteed core dump */
  205. }
  206.  
  207. long
  208. clip24(l)
  209. long l;
  210. {
  211.     if (l >= ((long)1 << 24))
  212.         return ((long)1 << 24) - 1;
  213.     else if (l <= -((long)1 << 24))
  214.         return -((long)1 << 24) + 1;
  215.     else
  216.         return l;
  217. }
  218.  
  219.  
  220.